import numpy as np
import pandas as pd
# 1.数据预处理（主要包括三样：缺失值，重复值和异常值）
df = pd.read_csv('train_.csv')
test = pd.read_csv('test_.csv')
# 处理异常值(并将异常值删除，将异常值视为缺失值）
for feature in df.columns:
    mean_value = df[feature].mean()
    std_value = df[feature].std()
    outlier_min = mean_value - 3 * std_value
    outlier_max = mean_value + 3 * std_value
    df.loc[(df[feature] < outlier_min) | (df[feature] > outlier_max), feature] = np.nan
# 在处理缺失值时，使用均值填充
df = df.fillna(df.mean())
# 删除重复值
df = df.drop_duplicates()
# 2.构建基于梯度下降法实现的线回性归模型
# step1.将数据向量化
X0 = np.ones((404, 1))
X1 = df[['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12']]
X1 = X1.values
X = np.hstack((X1, X0))
X = (X - np.mean(X, axis=0)) / (np.std(X, axis=0)+1e-12)
Y = df['outcome']
Y = Y.values
Y = Y.reshape(404, 1)
# 定义学习率和w
alpha = 0.1
W = np.random.uniform(low=-1/(13**(1/2)), high=1/(13**(1/2)), size=(14, 1))
# 定义最大迭代次数和早停参数
max_iters = 100000
tolerance = 1e-16
# 记录上一次的损失值
prev_loss = float('inf')
for i in range(max_iters):
    # 计算当前损失值
    loss = np.mean(np.square(Y - np.dot(X, W)))
    print(loss)
    # 判断是否满足早停条件
    if abs(loss - prev_loss) < tolerance:
        print("Early stopping at iteration ", i)
        break

    # 更新权重并计算梯度
    W = W - alpha * np.dot(X.T, np.dot(X, W) - Y) / len(Y)
    grad = np.dot(X.T, np.dot(X, W) - Y)

    # 更新上一次的损失值
    prev_loss = loss

print("输出参数w:", W[0:13])  # 前n个数是w
print("输出参数b:", W[13])  # 最后一个数（第n+1个数）是b

test = test.fillna(df.mean())
X0_test = np.ones((102, 1))
X1_test = test[['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12']]
X1_test = X1_test.values
X_test = np.hstack((X1_test, X0_test))
Y_test = np.dot(X_test, W)
Y_test = pd.DataFrame(Y_test)
Y_test.to_excel('text answer1.xlsx')






